Handle VMX domains correctly across xend restarts
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 11 Aug 2005 21:02:51 +0000 (21:02 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 11 Aug 2005 21:02:51 +0000 (21:02 +0000)
This patch remembers the device model pid across xend restarts and
avoids creating duplicate device model processes.

Also, device models don't inherit socket fds from xend (which are closed
on exec now), which used to prevent xend restarting.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
tools/python/xen/web/connection.py
tools/python/xen/web/reactor.py
tools/python/xen/web/tcp.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/image.py
tools/python/xen/xend/server/relocate.py

index 73607d3a60fdeedc52d7cdaaef71fa92cb519f14..9c526bd3412eca23111386bfea2728bfc57332cd 100644 (file)
@@ -20,6 +20,7 @@ import sys
 import threading
 import select
 import socket
+import fcntl
 
 from errno import EAGAIN, EINTR, EWOULDBLOCK
 
@@ -152,6 +153,9 @@ class SocketListener:
     def createSocket(self):
         raise NotImplementedError()
 
+    def setCloExec(self):
+        fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+
     def acceptConnection(self, sock, protocol, addr):
         return SocketServerConnection(sock, protocol, addr, self)
 
index 540354f27b21884a06c8508f5dde540e0dc784ba..2be9126988a69eb091c5a81db647445b2b742bd8 100644 (file)
@@ -16,4 +16,4 @@
 #============================================================================
 
 from unix import listenUNIX, connectUNIX
-from tcp import listenTCP, connectTCP
+from tcp import listenTCP, connectTCP, SetCloExec
index ce3c12ec57b92644325e693734b9c5613f3df362..ed57d45159a72d61c285c408060505f591212594 100644 (file)
@@ -85,6 +85,9 @@ def listenTCP(port, factory, interface='', backlog=None):
     l.startListening()
     return l
 
+def SetCloExec(SocketListener):
+    SocketListener.SetCloExec()
+
 def connectTCP(host, port, factory, timeout=None, bindAddress=None):
     c = TCPConnector(host, port, factory, timeout=timeout, bindAddress=bindAddress)
     c.connect()
index 1ec8ce2d6050709c31c2d4e4386985f10d47bed4..52fba1c4ca984cd18c78e809e6b462a539ea826d 100644 (file)
@@ -231,6 +231,7 @@ class XendDomainInfo:
         DBVar('restart_time',  ty='float'),
         DBVar('restart_count', ty='int'),
         DBVar('target',        ty='long', path="memory/target"),
+        DBVar('device_model_pid', ty='int'),
         ]
     
     def __init__(self, db):
@@ -275,6 +276,7 @@ class XendDomainInfo:
         self.vcpus = 1
         self.vcpusdb = {}
         self.bootloader = None
+        self.device_model_pid = 0
 
     def setDB(self, db):
         self.db = db
@@ -457,6 +459,8 @@ class XendDomainInfo:
             sxpr.append(devs)
         if self.config:
             sxpr.append(['config', self.config])
+        if self.device_model_pid:
+            sxpr.append(['device_model_pid',self.device_model_pid])
         return sxpr
 
     def sxpr_devices(self):
@@ -739,7 +743,8 @@ class XendDomainInfo:
                 ctrl.initController(reboot=True)
         else:
             self.create_configured_devices()
-        self.image.createDeviceModel()
+        if not self.device_model_pid:
+            self.device_model_pid = self.image.createDeviceModel()
 
     def device_create(self, dev_config):
         """Create a new device.
index 908299d626da621b175fbf7100922bf840d27c04..afa6d1da990155f92bf148c25441cd4da6084a3d 100644 (file)
@@ -262,7 +262,7 @@ class VmxImageHandler(ImageHandler):
     memmap = None
     memmap_value = []
     device_channel = None
-
+    pid = 0
     def createImage(self):
         """Create a VM for the VMX environment.
         """
@@ -379,6 +379,7 @@ class VmxImageHandler(ImageHandler):
         log.info("spawning device models: %s %s", device_model, args)
         self.pid = os.spawnve(os.P_NOWAIT, device_model, args, env)
         log.info("device model pid: %d", self.pid)
+        return self.pid
 
     def vncParams(self):
         # see if a vncviewer was specified
@@ -398,8 +399,11 @@ class VmxImageHandler(ImageHandler):
     def destroy(self):
         channel.eventChannelClose(self.device_channel)
         import signal
+        if not self.pid:
+            self.pid = self.vm.device_model_pid
         os.kill(self.pid, signal.SIGKILL)
         (pid, status) = os.waitpid(self.pid, 0)
+        self.pid = 0
 
     def getDomainMemory(self, mem_mb):
         # for ioreq_t and xenstore
index d19ec7c29ecacc3cdb0750d8290816263034d60f..01995193c92daf7d6dff52a664a93f10675cf57a 100644 (file)
@@ -140,7 +140,8 @@ def listenRelocation():
     if xroot.get_xend_relocation_server():
         port = xroot.get_xend_relocation_port()
         interface = xroot.get_xend_relocation_address()
-        reactor.listenTCP(port, factory, interface=interface)
+        l = reactor.listenTCP(port, factory, interface=interface)
+        l.setCloExec()
 
 def setupRelocation(dst, port):
     try: